/**
******************************************************************************
* @file           : mf_config.c
* @brief          : MCU FUNCTION CONFIG
******************************************************************************
* @attention
*
* Copyright (c) [2021] [Fudan Microelectronics]
* THIS SOFTWARE is licensed under Mulan PSL v2.
* can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*          http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*
******************************************************************************
*/

/* Includes ------------------------------------------------------------------*/
#include "mf_config.h"
#include "log.h"

/* Private function prototypes -----------------------------------------------*/

/**
 * @brief  SWD_IO Initialization function
 * @param  void
 * @retval None
 */
void MF_SWD_IO_Init(void)
{
  FL_GPIO_InitTypeDef GPIO_InitStruct;

  /* PD8 SWD_SWDIO */
  GPIO_InitStruct.pin = FL_GPIO_PIN_8;
  GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
  GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.pull = FL_DISABLE;
  GPIO_InitStruct.remapPin = FL_DISABLE;
  FL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /* PD7 SWD_SWCLK */
  GPIO_InitStruct.pin = FL_GPIO_PIN_7;
  GPIO_InitStruct.mode = FL_GPIO_MODE_DIGITAL;
  GPIO_InitStruct.outputType = FL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStruct.pull = FL_DISABLE;
  GPIO_InitStruct.remapPin = FL_DISABLE;
  FL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}

/**
 * @brief  NVIC Initialization function
 * @param  void
 * @retval None
 */
void MF_NVIC_Init(void)
{
  FL_NVIC_ConfigTypeDef InterruptConfigStruct;

  InterruptConfigStruct.preemptPriority = 0;
  FL_NVIC_Init(&InterruptConfigStruct, DMA_IRQn);
}

/**
 * @brief  HFDET_IRQHandler
 * @param  void
 * @retval None
 */
void HFDET_IRQHandler(void)
{
  // 停振检测中断处理
  if ((FL_FDET_IsEnabledIT_XTHFFail() == 0x01UL) && (FL_FDET_IsActiveFlag_XTHFFail() == 0x01UL))
  {
    FL_FDET_ClearFlag_XTHFFail();
    /*应用处理逻辑*/
  }
}

/**
 * @brief  Clock Initialization.
 * @retval None
 */
void MF_Clock_Init(void)
{
  /* Initial Low Speed Clock */
  FL_RCC_SetLSCLKClockSource(FL_RCC_LSCLK_CLK_SOURCE_LPOSC);

  /* Initial RCHF */
  FL_RCC_RCHF_SetFrequency(FL_RCC_RCHF_FREQUENCY_8MHZ);
  FL_RCC_RCHF_Enable();

  /* Initial PLL */
  FL_RCC_PLL_Disable();
  FL_RCC_PLL_SetClockSource(FL_RCC_PLL_CLK_SOURCE_RCHF);
  FL_RCC_PLL_SetPrescaler(FL_RCC_PLL_PSC_DIV8);
  FL_RCC_PLL_WriteMultiplier(63); /* 输出64MHz */
  FL_RCC_PLL_SetOutputMultiplier(FL_RCC_PLL_OUTPUT_X1);
  FL_RCC_PLL_Enable();
  while (FL_RCC_IsActiveFlag_PLLReady() != FL_SET)
    ;

  /* Initial System Clock */
  FL_FLASH_SetReadWait(FLASH, FL_FLASH_READ_WAIT_2CYCLE);    /* 设置FLASH读等待为 2 个周期 */
  FL_RCC_SetSystemClockSource(FL_RCC_SYSTEM_CLK_SOURCE_PLL); /* 设置系统主时钟为 PLL */
  FL_RCC_SetAHBPrescaler(FL_RCC_AHBCLK_PSC_DIV1);
  FL_RCC_SetAPB1Prescaler(FL_RCC_APB1CLK_PSC_DIV1);
  FL_RCC_SetAPB2Prescaler(FL_RCC_APB2CLK_PSC_DIV1);

  SystemCoreClockUpdate();
}

void MF_Config_Init(void)
{
  /* Initial SWD */
  MF_SWD_IO_Init();

  /* Initial NVIC */
  MF_NVIC_Init();

  uart0_send_str("sys init ok.\r\n");
}

/**
 * @brief DMA_IRQHandler
 * @return None
 * @note DMA中断函数
 */
void DMA_IRQHandler(void)
{
  /* uart_dma interrupt hadnle status start */
  if ((FL_ENABLE == FL_DMA_IsEnabledIT_TransferComplete(MF_UART0_DMA_BASE, MF_UART0_DMA_CHANNEL)) && (FL_SET == FL_DMA_IsActiveFlag_TransferComplete(MF_UART0_DMA_BASE, MF_UART0_DMA_CHANNEL)))
  {
    FL_DMA_ClearFlag_TransferComplete(MF_UART0_DMA_BASE, MF_UART0_DMA_CHANNEL); /* clear dma channel exchange_flag */
    while (FL_UART_IsActiveFlag_TXShiftBuffEmpty(MF_UART0_BASE) == FL_RESET)    /* wait uart_shift_reg end_bit send to peripheral */
    {
      /**对于DMA发送，DMA通道传输完成不代表数据全部发送完成，
       * 此时最后一字节数据还在UART的移位寄存器中还没发送完成，
       * 所以需要再等待最后一字节数据发送完成**/
    }
    FL_UART_ClearFlag_TXShiftBuffEmpty(MF_UART0_BASE); /* clear uart_shift_reg flag */
    FL_DMA_Disable(MF_UART0_DMA_BASE);
    FL_UART_DisableTX(MF_UART0_BASE);
  }
  /* uart_dma interrupt hadnle status end */

#if !MF_SPI1_DMA_ONLY_USE_TX
  /* spi1_dma interrupt hadnle status start */
  if ((FL_ENABLE == FL_DMA_IsEnabledIT_TransferComplete(MF_SPI1_DMA_BASE, MF_SPI1_DMA_RX_CHANNEL)) && (FL_SET == FL_DMA_IsActiveFlag_TransferComplete(MF_SPI1_DMA_BASE, MF_SPI1_DMA_RX_CHANNEL)))
  {
    FL_DMA_ClearFlag_TransferComplete(MF_SPI1_DMA_BASE, MF_SPI1_DMA_RX_CHANNEL); /* clear dma channel exchange_flag */
    mf_spi_dma_complete_flag(FL_SET);
  }
  /* spi1_dma interrupt hadnle status end */

#else
  /* spi1_dma interrupt hadnle status start */

  /* spi1_dma interrupt hadnle status end */

#endif
}

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
}
#endif /* USE_FULL_ASSERT */

/*************************(C) COPYRIGHT Fudan Microelectronics **** END OF FILE*************************/
